package service

import (
	"fitness/internal/dao"
	"fitness/internal/entity/system"
	"fitness/pkg/common"
	"fitness/pkg/constant"
	"fitness/pkg/tools"
	"fitness/pkg/utils/R"
	"fmt"
	"github.com/duke-git/lancet/v2/slice"
	"github.com/gin-gonic/gin"
	"net/http"
	"os"
	"strconv"
	"time"
)

type UserService struct {
	SysUserDao     *dao.SysUserDao
	UserRolesDao   *dao.SysUserRolesDao
	SysRoleDao     *dao.SysRoleDao
	SysRoleMenuDao *dao.SysRoleMenuDao
	HandlerError   *tools.HandlerError
}

func NewUserService(SysUserDao *dao.SysUserDao,
	UserRolesDao *dao.SysUserRolesDao,
	SysRoleDao *dao.SysRoleDao,
	SysRoleMenuDao *dao.SysRoleMenuDao,
	HandlerError *tools.HandlerError) *UserService {
	return &UserService{
		SysUserDao:     SysUserDao,
		UserRolesDao:   UserRolesDao,
		SysRoleDao:     SysRoleDao,
		SysRoleMenuDao: SysRoleMenuDao,
		HandlerError:   HandlerError,
	}
}

func (s *UserService) Me(c *gin.Context) {
	//获取用户信息
	userId := c.GetUint64(constant.UserId)
	sysUser, err := s.SysUserDao.FindSysUserById(userId)
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"code": 400,
			"msg":  "用户信息不存在",
		})
		return
	}
	var roles []string
	var perms []string
	//获取角色信息
	userRoles := s.UserRolesDao.FindRolesByUserId(userId)
	for _, userRole := range userRoles {
		form, err := s.SysRoleDao.GetRoleForm(*userRole.RoleId)
		if err != nil {
			c.JSON(http.StatusOK, gin.H{
				"code": 400,
				"msg":  "用户信息不存在",
			})
			return
		}
		roles = append(roles, form.Code)
		list := s.SysRoleMenuDao.GetRolePermsList(form.ID)
		for _, bo := range list {
			perms = append(perms, bo.Perms...)
		}
	}
	//权限
	perms = slice.Unique(perms)
	c.JSON(http.StatusOK, gin.H{
		"code": 200,
		"msg":  "验证成功,正在跳转",
		"data": gin.H{
			"avatar":   sysUser.Avatar,
			"nickname": sysUser.NickName,
			"perms":    perms,
			"roles":    roles,
			"userId":   sysUser.ID,
			"userType": sysUser.UserType,
			"username": sysUser.UserName,
		},
	})
}

func (s *UserService) Page(c *gin.Context) {
	var pageQuery system.SysUserPageQuery
	err := c.ShouldBindQuery(&pageQuery)
	if err != nil {
		c.JSON(http.StatusOK, R.ReturnFailMsg(err.Error()))
		return
	}

	users, err := s.SysUserDao.ListPagedUsers(pageQuery)
	if err != nil {
		c.JSON(http.StatusOK, R.ReturnFailMsg(err.Error()))
		return
	}
	c.JSON(http.StatusOK, R.ReturnSuccess(users))
}

func (s *UserService) GetUserForm(c *gin.Context) {
	userIdStr := c.Param("userId")
	// 尝试将字符串转换为整数
	userId, err := strconv.ParseUint(userIdStr, 10, 64)
	if err != nil {
		// 如果转换失败，返回错误响应
		c.JSON(http.StatusOK, R.ReturnFailMsg("错误的用户ID"))
		return
	}
	userForm, err := s.SysUserDao.GetUserForm(userId)
	if err != nil {
		// 如果转换失败，返回错误响应
		c.JSON(http.StatusOK, R.ReturnFailMsg("查询失败"))
		return
	}
	c.JSON(http.StatusOK, R.ReturnSuccess(userForm))
}

func (s *UserService) UpdateUser(c *gin.Context) {
	var userForm system.UserForm
	err := c.ShouldBindJSON(&userForm)
	if err != nil {
		c.JSON(http.StatusOK, R.ReturnFailMsg("修改用户失败"))
		return
	}

	result, err := s.SysUserDao.UpdateUser(userForm)
	if err != nil {
		c.JSON(http.StatusOK, R.ReturnFailMsg(err.Error()))
		return
	}
	c.JSON(http.StatusOK, R.ReturnSuccess(result))
}

func (s *UserService) Avatar(c *gin.Context) {
	//获取上传的图像
	f, err := c.FormFile("avatarfile")
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"code": 400,
			"msg":  "上传失败!",
		})
		return
	} else {
		isMainUploadExist, _ := tools.IsFileExist(common.Upload)
		if !isMainUploadExist {
			os.Mkdir(common.Upload, os.ModePerm)
		}
		fileName := tools.Md5(fmt.Sprintf("%s%s", f.Filename, time.Now().String()))
		fileDir := fmt.Sprintf("%s%d%s/", common.Upload, time.Now().Year(), time.Now().Month().String())
		isExist, _ := tools.IsFileExist(fileDir)
		if !isExist {
			_ = os.Mkdir(fileDir, os.ModePerm)
		}
		filepath := fmt.Sprintf("%s%s%s", fileDir, fileName, ".png")
		err := c.SaveUploadedFile(f, filepath)
		if err != nil {
			c.JSON(http.StatusOK, R.ReturnFailMsg(err.Error()))
			return
		}
		userId := c.GetUint64(constant.UserId)
		_, err = s.SysUserDao.UpdateAvatar(userId, filepath)
		if err != nil {
			c.JSON(http.StatusOK, R.ReturnFailMsg(err.Error()))
			return
		}
		c.JSON(http.StatusOK, R.ReturnSuccess(gin.H{
			"path": filepath,
		}))
	}
}
